package main

import (
	"fmt"
	"github.com/tarm/serial"
	"log"
	"serial/config"
	"serial/sink"
	"sync"
)

var gw sync.WaitGroup

type Sink func(data string)

func transferSerial(ch <-chan byte, sinks ...Sink) {
	var data []byte
	for val := range ch {
		if val == 36 { //$
			data = make([]byte, 0)
			data = append(data, val)
		} else if val == 10 { //\n
			data = append(data, val)
			str := string(data)
			for _, sinkWay := range sinks {
				sinkWay(str)
			}
			data = make([]byte, 0)
		} else {
			data = append(data, val)
		}
	}
}

func sourceSerial(serialParam config.SerialParam, ch chan<- byte) {
	// 打开串口
	serialConfig := &serial.Config{
		Name: fmt.Sprintf("/dev/%v", serialParam.Name),
		Baud: serialParam.Baud,
	}
	port, err := serial.OpenPort(serialConfig)
	if err != nil {
		log.Fatal(err)
	}
	defer func(port *serial.Port) {
		err := port.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(port)

	// 读取串口数据
	buffer := make([]byte, 512)
	for {

		n, err := port.Read(buffer)
		if err != nil {
			log.Fatal(err)
		}
		if n > 0 {
			for i := 0; i < n; i++ {
				ch <- buffer[i]
			}
		}
	}
}

func main() {
	gw.Add(1)
	serialParams := config.Conf.SerialParams
	for _, serialParam := range serialParams {
		var ch = make(chan byte, 512)
		go sourceSerial(serialParam, ch)
		go transferSerial(ch, func(data string) {
			topic := fmt.Sprintf("serial/%v/%v", config.Conf.DeviceCode, serialParam.Name)
			publish := sink.Publish(topic, 1, false, data)
			fmt.Printf("%v=>%t=>%v", serialParam.Name, publish, data)
		})
	}
	gw.Wait()
}
